package com.zhdl.modules.process;

import com.zhdl.common.ytools.callback.BoolCallback;
import com.zhdl.common.ytools.callback.CommonCallback;
import com.zhdl.modules.common.warn.service.RunWarnService;
import com.zhdl.modules.demo.testprocess.ProcessOptInterface;
import com.zhdl.modules.process.dto.MyEx;
import com.zhdl.modules.process.dto.ProcessBean;
import com.zhdl.modules.process.dto.ScheduleData;
import com.zhdl.modules.process.dto.VerifyData;
import com.zhdl.modules.process.task.CustomizeTask;
import com.zhdl.modules.process.task.DynamicTask;
import com.zhdl.modules.process.verify.DelayTimeVerify;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public abstract class BaseProcess implements CommonProcess {
    public StatusHolder statusHolder = new StatusHolder();
    public String desc;
    public boolean allAlarm = false;
    @Resource
    RunWarnService runWarnService;
    public int process;
    public List<MyEx> alarmList = new ArrayList<>();
    @Resource
    public DynamicTask dynamicTask;
    //线程池
    //任务管理器
    public List<BaseProcess> childList = new ArrayList<>();
    private final ScheduleData scheduleData = new ScheduleData();
    public int VeryInterval = 100;

    @Override
    public void initHardware() {
        statusHolder.setRunWarnService(runWarnService);
    }

    @Override
    public void initLocation(CommonCallback<String> complete) {
        if (!childList.isEmpty()) {
            for (BaseProcess baseProcess : childList) {
                baseProcess.initLocation(complete);
            }
        }
    }

    public VerifyData getVerifyByStep(Integer step, List<VerifyData> verifyDataList) {
        VerifyData verify = null;
        for (VerifyData verifyData : verifyDataList) {
            if (verifyData.getStep() == step.intValue()) {
                verify = verifyData;
                break;
            }
        }
        return verify;
    }


    @Override
    public boolean checkStartItems() {
        return true;
    }

    //开始流程
    @Override
    public boolean start() {
        return true;
    }

    //暂停流程
    @Override
    public void stop() {
        //停止标志

    }

    //继续流程
    @Override
    public void onPause() {
        //状态标为未启动


    }

    //结束重置状态
    public void release() {

    }


    //设置报警信息
    @Override
    public void setExCallBack(CommonCallback<MyEx> callback) {

    }


    //报警复位
    @Override
    public void cancelAlarm() {
        allAlarm = false;
        alarmList.clear();
        if (!childList.isEmpty()) {
            for (BaseProcess baseProcess : childList) {
                baseProcess.cancelAlarm();
            }
        }
    }

    //传递SSE数据
    @Override
    public void setSSEData(CommonCallback<String> callback) {

    }

    /**
     * 开启校验
     */
    @Override
    public void openCheck(CommonCallback<Map<String, String>> callback) {

    }

    /**
     * 流程进度回调
     *
     * @param callback 流程步数回调
     */
    @Override
    public void processCallBack(BoolCallback<Integer> callback) {

    }

    /**
     * 队列
     *
     * @param completeMap 队列
     */
    @Override
    public void setCompleteMap(Map<Integer, Boolean> completeMap) {

    }

    public void startABS(float speed, float distance) {

    }

    public List<ProcessBean> processBeanList;

    public List<ProcessBean> getProcessBeanList() {
        return processBeanList;
    }

    public ProcessBean getProcessByStep(Integer step) {
        for (ProcessBean processBean : processBeanList) {
            if (processBean.getStep().equals(step)) {
                return processBean;
            }
        }
        return null;
    }

    @Override
    public void startProcess(Integer process) {
        ProcessBean processByStep = processBeanList.get(process);
        if (processByStep != null) {
            statusHolder.process = process;
            if (process == 0 && statusHolder.yield > 0) {
                log.info("本次流程数据{}", processBeanList);
                initProcessList();
            }
            if (process == processBeanList.size() - 1) {
                maxStepCallback(processByStep);
            } else {
                processByStep.setStep(process+1);
            }

            processByStep.getProcessDo().doSomeThing();
            if (processByStep.getProcessVerify() == null) {
                processByStep.setProcessVerify(new DelayTimeVerify(2000));
            }
            processByStep.setRunStatus(1);
            dynamicTask.startTask(new CustomizeTask(processByStep, statusHolder), VeryInterval);
        }
    }

    public  abstract void initProcessList();
    public void maxStepCallback(ProcessBean maxStep){
        maxStep.setStep(-1);
    }
    @Data
    public static class StatusHolder {
        public boolean isStart = false, isRunning = false, initComplete = false, isStop = false, isAuto = true, allAlarm = false, testModel = false;
        public int process = -1;
        public int yield = 0;
        public ProcessOptInterface optInterface;
        public String processName;
        public RunWarnService runWarnService;
        public void release() {
            isStart = false;
            isRunning = false;
            initComplete = false;
            isStop = false;
            allAlarm = false;
            process = -1;
            yield = 0;
            if (optInterface != null) {
                optInterface.release();
            }
        }
        /**
         * 完成单次循环后调用方法 复位一些标记
         */
        public void completeOnceCirculate() {
            isStart = false;
            isRunning = false;
            process = -1;
            yield++;
            if (optInterface != null) {
                optInterface.release();
            }
        }

        public boolean start() {
            optInterface.start();
            if (allAlarm) {
                log.info("先复位报警!!");
                return false;
            }
            if (!isAuto) {
                log.info("请先切换到自动模式");
                return false;
            }
            if (!initComplete) {
                log.info("初始化未完成!!");
                return false;
            }
            if (isRunning) {
                log.info("流程正在进行 无需重复start");
                isStop = false;
                isStart = true;
                return false;
            }
            isStart = true;
            //流程运行标志
            isRunning = true;
            isStop = false;
            //流程开始时，判断是否是由暂停开始
            if (process == -1) {
                process = 0;
            }
            if (optInterface != null) {
                optInterface.startProcess(process);
            }
            return true;
        }

        public void startProcess(Integer process) {
            if (allowStart(process)) {
                if (optInterface != null) {
                    optInterface.startProcess(process);
                }
            } else {
                log.info("流程标记不满足继续条件!不能继续~!~");
            }
        }

        public void test(Integer process) {
            this.process = process;
            isRunning = false;
            isStart = false;
            log.info("流程单步运行模式执行完" + process + "停止等待开始指令!!!!!!");
        }

        public void stop() {
            isStart = false;
            isStop = true;
            optInterface.stop();
        }

        public void childStop(){
            optInterface.stop();
        }
        public void reset() {
            allAlarm = false;
            optInterface.reset();
        }
        public void addEx(int code,String desc){
            if (runWarnService!=null){
                runWarnService.addNewWarnService(desc,code);
            }
            allAlarm = true;
            isRunning = false;
            stop();
        }
        public void setTestModel(boolean testModel){
            this.testModel = testModel;
        }
        private boolean allowStart(int process) {
            if (!isStart && isStop) {
                isStop = false;
                isRunning = false;
                this.process = process;
                log.info(getClass().getName() + "任务暂停后未完成任务完成");
                return false;
            }
            if (!isStart || !isRunning || !initComplete || !isAuto) {
                log.info("不满足流程继续条件isStart: " + isStart + "-----isRunning: " + isRunning + "------initComplete: " + initComplete + "-------isAuto: " + isAuto);
                return false;
            }
            if (process == 0) {
                yield++;
                log.info(getClass().getName() + "当前运行产量: " + yield);
            }
            this.process = process;
            return true;
        }
    }
}
